package com.security.door.utils.collectionUtil;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.dozer.util.ReflectionUtils;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;


/**
 * Created by jq on 2017/12/29
 *
 * @author jq
 */
public class MapUtil {

    /**
     * 把List<T>，提取Object中的某个属性值key，转为Map<key, T>，有重复的key则舍去之前的对象
     * 经测试，和普通的两边for循环写法性能基本一致，甚至更快
     *
     * @param list    待转换的List
     * @param keyName List对象中的某个属性名
     */
    public static <K, T> Map<K, T> toMap(List<T> list, String keyName) {
        Map<K, T> resultMap = Maps.newHashMap();
        if (list == null || list.isEmpty()) {
            return resultMap;
        }
        try {
            Field getField = ReflectionUtils.getFieldFromBean(list.get(0).getClass(), keyName);
            getField.setAccessible(true);
            for (T object : list) {
                resultMap.put((K) getField.get(object), object);
            }
        } catch (Exception ignored) {
        }
        return resultMap;
    }

    /**
     * 把List<T>，提取Object中的某个属性值key,转为Map<key, List<T>>。不合并重复
     *
     * @param list    待转换的List
     * @param keyName List对象中的某个属性名
     */
    public static <K, T> Map<K, List<T>> toMapList(List<T> list, String keyName) {
        Map<K, List<T>> resultMap = Maps.newHashMap();
        if (list == null || list.isEmpty()) {
            return resultMap;
        }

        try {
            Field getField = ReflectionUtils.getFieldFromBean(list.get(0).getClass(), keyName);
            getField.setAccessible(true);
            for (T one : list) {
                K key = (K) getField.get(one);
                if (key == null) {
                    continue;
                }
                List<T> valueList = resultMap.get(key);
                if (valueList == null) {
                    valueList = Lists.newArrayList();
                    resultMap.put(key, valueList);
                }
                valueList.add(one);
            }
        } catch (Exception ignored) {
        }
        return resultMap;
    }

    /**
     * 将一个 JavaBean 对象转化为一个  Map
     * 尽量不要使用
     *
     * @param obj 要转化的JavaBean 对象
     * @return 转化出来的  Map 对象
     * @throws IllegalAccessException 如果实例化 JavaBean 失败
     */
    public static Map<String, Object> beanToMap(Object obj)  {
        if (obj == null) {
            return null;
        }
        Map<String, Object> map = Maps.newHashMap();
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor property : propertyDescriptors) {
                String key = property.getName();
                // 过滤class属性
                if (!key.equals("class")) {
                    // 得到property对应的getter方法
                    Method getter = property.getReadMethod();
                    Object value = getter.invoke(obj);
                    if (value != null) {
                        map.put(key, value);
                    }
                }
            }
        }catch (Exception ignored){
        }
        return map;
    }
}
